﻿using AutoMapper;
using Azure.Core;
using MediatR;
using TaskProject.Application.Command.BOM;
using TaskProject.Domain.BOM;
using TaskProject.ErrorCode;
using TaskProject.InfrasIntructure.Implement;

namespace TaskProject.Application.Handler.BOM
{
    public class AddBOMHandler : IRequestHandler<AddBOMCommand, APIResult<int>>
    {
        DatabaseContext db;
        IMapper mapper;

        public AddBOMHandler(DatabaseContext db, IMapper mapper)
        {
            this.db = db;
            this.mapper = mapper;
        }

        public async Task<APIResult<int>> Handle(AddBOMCommand request, CancellationToken cancellationToken)
        {
            APIResult<int> res=new APIResult<int>();
            var productExits = await db.sqlSugar.Queryable<ProductModel>().Where(c => c.ProductId == request.ProductId && !c.IsDel).AnyAsync(cancellationToken);
            if(!productExits)
            {
                res.Code = APIEnum.Fail;
                res.Msg = "产品不存在";
                return res;
            }
            if(request.Materials==null || !request.Materials.Any())
            {
                res.Code = APIEnum.Fail;
                res.Msg = "请至少选择一个物料";
                return res;
            }
            var MaterialIds = request.Materials.Select(m => m.MaterialId).ToList();
            var MaterialExits = await db.sqlSugar.Queryable<MaterialModel>().Where(c => MaterialIds.Contains(c.MaterialId) && !c.IsDel).ToListAsync(cancellationToken);
            if (MaterialExits.Count!=MaterialIds.Count)
            {
                var missingIds=MaterialIds.Except(MaterialExits.Select(m=>m.MaterialId)).ToList();
                res.Code = APIEnum.Fail;
                res.Msg = $"物料不存在{string.Join(",",missingIds)}";
                return res;
            }
            var BOMExits = await db.sqlSugar.Queryable<BOMModel>().Where(c => c.ProductId == request.ProductId && MaterialIds.Contains(c.MaterialId) && !c.IsDel).ToListAsync(cancellationToken);
            if (BOMExits.Any())
            {
                var existMaterialProductIds=BOMExits.Select(m=>m.MaterialId).ToList();
                res.Code = APIEnum.Fail;
                res.Msg = $"该物料已在此产品的BOM中存在，请勿重复添加{string.Join(",",existMaterialProductIds)}";
                return res;
            }
            var bomsTolist = new List<BOMModel>();
            foreach(var materialId in request.Materials)
            {
                var model = mapper.Map<BOMModel>(request);
                model.BOMId = await GetNextBOMIdAsync();
                model.MaterialId=materialId.MaterialId;
                model.PartNum = materialId.PartNum;
                model.LossRate = materialId.LossRate;
                model.BOMState = model.BOMState == true ? false : model.BOMState;
                model.IsDel = false;
                model.CreteName = "张三";
                model.CreteDate = DateTime.Now;
                model.CreateDesc = "新增了一条BOM";
                bomsTolist.Add(model);
            }
            
            try
            {
               
                int r = await db.sqlSugar.Insertable(bomsTolist).ExecuteCommandAsync(cancellationToken);

                res.Msg = "BOM添加成功";
                res.Code = APIEnum.Success;
                res.Data = r;
            }
            catch (Exception ex)
            {
                res.Code = APIEnum.Fail;
                res.Msg = $"添加失败：{ex.Message}";
            }

            return res;
        }

        private async Task<int> GetNextBOMIdAsync()
        {
            var maxId = await db.sqlSugar.Queryable<BOMModel>().MaxAsync(b => (int?)b.BOMId) ?? 0;
            return maxId+1;
        }
    }
}
